package com.sws.device.util;


import com.sws.device.domain.DevDeviceDTO;
import com.sws.device.service.DevDeviceWebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Token管理工具类
 */
@Component("deviceTokenUtil")
public class TokenUtil {
    
    // 设备Token映射 (deviceSn -> token)
    private static final Map<String, String> DEVICE_TOKENS = new ConcurrentHashMap<>();
    
    // Token过期时间映射 (token -> expireTime)，单位：毫秒
    private static final Map<String, Long> TOKEN_EXPIRES = new ConcurrentHashMap<>();
    
    // Token默认过期时间，单位：秒
    private static final int DEFAULT_EXPIRE = 3600;
    
    // 设备服务
    private static DevDeviceWebSocketService deviceService;
    
    @Autowired
    public void setDeviceService(DevDeviceWebSocketService deviceService) {
        TokenUtil.deviceService = deviceService;
    }
    
    /**
     * 生成新的Token
     *
     * @param deviceSn 设备序列号
     * @return 生成的Token
     */
    public static String generateToken(String deviceSn) {
        String token = UUID.randomUUID().toString().replace("-", "");
        DEVICE_TOKENS.put(deviceSn, token);
        TOKEN_EXPIRES.put(token, System.currentTimeMillis() + DEFAULT_EXPIRE * 1000L);
        return token;
    }
    
    /**
     * 更新Token
     *
     * @param deviceSn 设备序列号
     * @return 更新后的Token
     */
    public static String updateToken(String deviceSn) {
        // 这里简单实现，直接复用当前的Token，只更新过期时间
        String token = DEVICE_TOKENS.get(deviceSn);
        if (token == null) {
            return generateToken(deviceSn);
        }
        
        // 更新过期时间
        TOKEN_EXPIRES.put(token, System.currentTimeMillis() + DEFAULT_EXPIRE * 1000L);
        return token;
    }
    
    /**
     * 验证Token是否有效
     *
     * @param token     要验证的Token
     * @param deviceSn  设备序列号
     * @return 是否有效
     */
    public static boolean validateToken(String token, String deviceSn) {
        if (token == null || deviceSn == null) {
            return false;
        }
        
        // 从数据库验证Token是否匹配
        if (deviceService != null) {
            DevDeviceDTO device = deviceService.getDeviceBySn(deviceSn);
            if (device != null && token.equals(device.getToken())) {
                // 检查是否过期
                Date tokenExpireTime = device.getTokenExpireTime();
                if (tokenExpireTime != null && tokenExpireTime.after(new Date())) {
                    return true;
                }
            }
            return false;
        }
        
        // 如果没有数据库服务，则使用本地缓存进行验证
        // 验证Token是否匹配
        String storedToken = DEVICE_TOKENS.get(deviceSn);
        if (storedToken == null || !storedToken.equals(token)) {
            return false;
        }
        
        // 验证Token是否过期
        Long expireTime = TOKEN_EXPIRES.get(token);
        return expireTime != null && expireTime > System.currentTimeMillis();
    }
    
    /**
     * 获取Token剩余有效时间
     *
     * @param token    Token
     * @param deviceSn 设备序列号
     * @return 剩余有效时间（秒）
     */
    public static int getTokenExpire(String token, String deviceSn) {
        // 从数据库获取Token信息
        if (deviceService != null) {
            DevDeviceDTO device = deviceService.getDeviceBySn(deviceSn);
            if (device != null && token.equals(device.getToken())) {
                Date tokenExpireTime = device.getTokenExpireTime();
                if (tokenExpireTime != null) {
                    long currentTimeMillis = System.currentTimeMillis();
                    long expireTimeMillis = tokenExpireTime.getTime();
                    long remainingMillis = expireTimeMillis - currentTimeMillis;
                    
                    // 转换为秒并确保不小于0
                    return (int) Math.max(0, remainingMillis / 1000);
                }
            }
        }
        
        // 如果没有数据库服务，则使用本地缓存
        Long expireTime = TOKEN_EXPIRES.get(token);
        if (expireTime == null) {
            return 0;
        }
        
        long remainTime = expireTime - System.currentTimeMillis();
        return (int) Math.max(0, remainTime / 1000);
    }
    
    /**
     * 移除Token
     *
     * @param deviceSn 设备序列号
     */
    public static void removeToken(String deviceSn) {
        String token = DEVICE_TOKENS.remove(deviceSn);
        if (token != null) {
            TOKEN_EXPIRES.remove(token);
        }
    }
    
    /**
     * 计算Token过期时间
     *
     * @param expireSeconds 过期秒数
     * @return Token过期时间
     */
    public static Date calculateTokenExpireTime(int expireSeconds) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.SECOND, expireSeconds);
        return calendar.getTime();
    }
} 